﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once

#include "IPlaneCurve3d.h"

namespace gcmp
{
    class IArc2d;

    /// \brief 三维圆弧
    ///
    class IArc3d : public IPlaneCurve3d
    {
        DEFINE_CAST_DERIVED(gcmp::IArc3d, gcmp::IPlaneCurve3d);
    public:
        /// \brief 根据圆心，半径，起始角度，终止角度构造三维圆弧(方向为逆时针)
        /// \param centerPoint   坐标系原点，圆弧圆心
        /// \param normalizedDirectionX       坐标系X轴单位向量
        /// \param normalizedDirectionY       坐标系Y轴单位向量
        /// \param radius     圆弧半径
        /// \param startAngle 起始角度（弧度）
        /// \param endAngle   终止角度（弧度）
        /// \param antiClockwise  弧顺逆方向，true：逆时针， false：顺时针
        /// \return  三维圆弧
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IArc3d> Create(
            const Vector3d & centerPoint,
            const Vector3d & normalizedDirectionX,
            const Vector3d & normalizedDirectionY,
            double radius,
            double startAngle,
            double endAngle,
            bool antiClockwise = true);

        /// \brief 根据空间中三点构造空间平面圆弧曲线
        /// \param startPoint  圆弧起点
        /// \param endPoint    圆弧终点
        /// \param referencePoint    参考点
        /// \return  三维圆弧
        /// \see 要求三点不重合且不共线
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IArc3d> Create(
            const Vector3d & startPoint,
            const Vector3d & endPoint,
            const Vector3d & referencePoint
        );

        /// \brief 根据空间中圆心、起点、终点和顺逆时针构造空间平面圆弧
        ///
        /// 其中圆弧法线方向由起点圆心矢量，根据右手规则，沿着起点圆心矢量与终点圆心矢量小于180度夹角的方向，叉乘终点圆心矢量所得。
        /// 顺逆时针方向是基于上述圆弧法线方向而定, 而不是一定基于矢量（0，0，1）。
        /// \param centerPoint 圆弧圆心
        /// \param startPoint  圆弧起点
        /// \param endPoint    圆弧终点
        /// \param antiClockwise  弧顺逆方向，true：逆时针， false：顺时针
        /// \return  三维圆弧
        /// \see 要求三点不重合且不共线
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IArc3d> Create(
            const Vector3d & centerPoint,
            const Vector3d & startPoint,
            const Vector3d & endPoint,
            bool antiClockwise
        );

        /// \brief 根据圆心，X轴，Y轴，二维圆弧构造空间圆弧
        /// \param centerPoint   坐标系原点，圆弧圆心
        /// \param normalizedDirectionX       坐标系X轴单位向量
        /// \param normalizedDirectionY       坐标系Y轴单位向量
        /// \param pIArc2d  二维圆弧
        /// \return  三维圆弧
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IArc3d> Create(
            const Vector3d & centerPoint,
            const Vector3d & normalizedDirectionX,
            const Vector3d & normalizedDirectionY,
            const IArc2d *pIArc2d);

        /// \brief 根据空间中圆心、起点、终点、参考法向和顺逆时针构造空间平面圆弧
        ///
        /// \param centerPoint 圆弧圆心
        /// \param startPoint  圆弧起点
        /// \param endPoint    圆弧终点
        /// \param normal      圆弧参考法向，要求与圆弧所在平面垂直
        /// \param antiClockwise  弧顺逆方向，true：逆时针， false：顺时针
        /// \return  三维圆弧
        /// \see 要求起点和终点共圆，默认容差为1e-4；要求半径长度不能过小，默认容差为1e-4
        GCMP_GEOMETRY_INTERFACE_EXPORT static OwnerPtr<IArc3d> Create(
            const Vector3d & centerPoint,
            const Vector3d & startPoint,
            const Vector3d & endPoint,
            const Vector3d & normal,
            bool antiClockwise
        );


    public:

        /// \brief 获取圆心
        /// \return 圆心
        virtual Vector3d GetCenter() const = 0;

        /// \brief 设置圆心
        /// \param centerPoint 圆心
        /// \return 成功返回true,否则返回false
        virtual bool SetCenter(const Vector3d& centerPoint) = 0;

        /// \brief  获取半径
        /// \return  半径
        virtual double GetRadius() const = 0;

        /// \brief  设置半径
        /// \param radius 半径
        /// \return  成功返回true,否则返回false
        virtual bool SetRadius(double radius) = 0;

        /// \brief 获取起始角度（弧度）
        /// \return  起始角度（弧度）
        virtual double GetStartAngle() const = 0;

        /// \brief 获取终止角度（弧度）
        /// \return  终止角度（弧度）
        virtual double GetEndAngle() const = 0;

        /// \brief 获取顺时针或逆时针方向，true：逆时， false：顺时
        /// \return  时针方向
        virtual bool IsAntiClockwise() const = 0;

        /// \brief  设置顺时针或逆时针方向
        /// \param antiClockwise  时针方向, true：逆时， false：顺时
        virtual void SetAntiClockwise(bool antiClockwise) = 0;

    public:
        virtual ~IArc3d() {}
    };
}
